//====cache.es6====//

let cachedInstances = {}
	, cachedData = {};

const supportLocalStorage = !(typeof localStorage === 'undefined' && localStorage === null);

class LocalCached {

	key = '';

	constructor(key) {
		if (cachedInstances[key])
			return cachedInstances[key];

		Object.defineProperties(this, {
			key: {
				value     : key,
				readable  : true,
				writable  : false,
				enumerable: true
			}
		});

		cachedInstances[key] = this;
	}

	loadData() {
		if (!cachedData[this.key]) {
			cachedData[this.key] = supportLocalStorage ? jsonDecode(localStorage.getItem(this.key), {}) : {};
		}
		return cachedData[this.key];
	}

	updateData() {
		if (supportLocalStorage) {
			localStorage.setItem(this.key, jsonEncode(this.data));
		}
		return this;
	}

	get data() {
		return this.loadData();
	}

	toString() {
		return jsonEncode(this.data);
	}

	has(name) {
		let cache = this.get(name);
		return typeof cache !== 'undefined';
	}

	get(name) {
		let cached = this.loadData();
		return cached[name] || undefined;
	}

	set(name, data) {
		let cached = this.loadData();
		cached[name] = data;
		this.updateData();
		return this;
	}
};

Object.defineProperties(LocalCached, {
	supportLocalStorage: {
		value     : supportLocalStorage,
		readable  : true,
		writable  : false,
		enumerable: true
	}
});

class SourceCached extends LocalCached {

	verify(data) {
		if (data && data.date && data.date > 0 && data.length && data.length > 0 && data.text && data.text != null)
			return data;
		return false;
	}

	compare(name, date, length) {
		var cache = this.get(name);
		if (cache === false || cache.date < date || cache.length !== length)
			return false;
		return cache;
	}

	get(name) {
		return this.verify(super.get(name));
	}

	set(name, cache) {
		if (this.verify(cache)) {
			super.set(name, cache);
		}
		return this;
	}
}